#include "iostream"
#include "string"

using namespace std;

// 提前让编译器知道Person类存在
template<class T1, class T2>
class Person004;

// 类外实现，全局函数没必要添加作用域 Person004::
template<class T1, class T2>
void printPerson2(Person004<T1, T2> p) {
    cout << "类外姓名" << p.name << "类外年龄" << p.age << endl;
}

template<class T1, class T2>
class Person004 {

    // 全局函数 类内实现
    friend void printPerson(Person004<T1, T2> p) {
        cout << "姓名" << p.name << "年龄" << p.age << endl;
    }

    // 全局函数 类外实现
    // 加空模板参数列表
    // 如果全局函数 是类外实现，需要让编译器提前知道这个函数的存在
    friend void printPerson2<>(Person004<T1, T2> p);
private:
    T1 name;
    T2 age;

public:
    Person004(T1 name, T2 age) : name(name), age(age) {}
};





void test01() {
    Person004<string, int> p("Tom", 20);
    printPerson(p);
}

void test02() {
    Person004<string, int> p("Tom1", 20);
    printPerson2(p);
}


int main() {
    test01();
    test02();
}